package log

import (
	"github.com/sirupsen/logrus"
)

var (
	std = logrus.StandardLogger()
)

type field struct {
	key   string
	value interface{}
}

func Field(key string, value interface{}) field {
	return field{
		key:   key,
		value: value,
	}
}

func splitArgs(args ...interface{}) (fs logrus.Fields, args0 []interface{}) {
	if len(args) == 0 {
		return fs, args0
	}

	if len(args) == 1 {
		f, ok := args[0].(field)
		if ok {
			return logrus.Fields{f.key: f.value}, args0
		} else {
			return fs, args
		}
	}

	fs = make(logrus.Fields)
	args0 = make([]interface{}, len(args))
	for i := range args {
		f, ok := args[i].(field)
		if ok {
			fs[f.key] = f.value
		} else {
			args0 = append(args0, args[i])
		}
	}
	return fs, args0
}

// Trace logs a message at level Trace on the standard logger.
func Trace(args ...interface{}) {
	fs, args0 := splitArgs(args)
	std.WithFields(fs).Traceln(args0...)
}

// Debug logs a message at level Debug on the standard logger.
func Debug(args ...interface{}) {
	fs, args0 := splitArgs(args)
	std.WithFields(fs).Debugln(args0...)
}

// Info logs a message at level Info on the standard logger.
func Info(args ...interface{}) {
	fs, args0 := splitArgs(args)
	std.WithFields(fs).Infoln(args0...)
}

// Warn logs a message at level Warn on the standard logger.
func Warn(args ...interface{}) {
	fs, args0 := splitArgs(args)
	std.WithFields(fs).Warnln(args0...)
}

// Error logs a message at level Error on the standard logger.
func Error(args ...interface{}) {
	fs, args0 := splitArgs(args)
	std.WithFields(fs).Errorln(args0...)
}

// Fatal logs a message at level Fatal on the standard logger then the process will exit with status set to 1.
func Fatal(args ...interface{}) {
	fs, args0 := splitArgs(args)
	std.WithFields(fs).Fatalln(args0...)
}

// Tracef logs a message at level Trace on the standard logger.
func Tracef(format string, args ...interface{}) {
	std.Tracef(format+"\n", args...)
}

// Debugf logs a message at level Debug on the standard logger.
func Debugf(format string, args ...interface{}) {
	std.Debugf(format+"\n", args...)
}

// Infof logs a message at level Info on the standard logger.
func Infof(format string, args ...interface{}) {
	std.Infof(format+"\n", args...)
}

// Warnf logs a message at level Warn on the standard logger.
func Warnf(format string, args ...interface{}) {
	std.Warnf(format+"\n", args...)
}

// Errorf logs a message at level Error on the standard logger.
func Errorf(format string, args ...interface{}) {
	std.Errorf(format+"\n", args...)
}

// Fatalf logs a message at level Fatal on the standard logger then the process will exit with status set to 1.
func Fatalf(format string, args ...interface{}) {
	std.Fatalf(format, args)
}
